<template>
  <a-popover :open="openPopover" placement="bottom" trigger="click" overlay-class-name="mt-2 w-[480px]" @open-change="onPopoverChange">
    <template #content>
      <div class="px-4 py-2">
        <a-tabs v-model:active-key="activeTab" @change="onChangeTab">
          <a-tab-pane key="0">
            <template #tab>
              <a-badge :count="unReadCount" :style="{ minWidth: '16px', height: '16px', lineHeight: '16px' }" :offset="[4, -4]">未读</a-badge>
            </template>
          </a-tab-pane>
          <a-tab-pane key="1" tab="已读" />
          <template v-if="activeTab === '0'" #rightExtra>
            <a-button ghost type="primary" size="small" @click="onReadAll">全部已读 </a-button>
          </template>
        </a-tabs>
        <div ref="scrollRef" class="h-[360px] overflow-auto" @scroll="onScroll">
          <a-collapse v-if="dataSource.length !== 0" v-model:active-key="activeCollapse" :bordered="false" class="bg-white" expand-icon-position="end">
            <a-collapse-panel v-for="item in dataSource" :key="item.id" @click="onChangeCollapse(item)">
              <template #header>
                <div>
                  <a-badge v-if="!item.isRead && activeTab === '0'" status="processing" />
                  <a-tag v-if="item.msgLevel === '重要'" color="blue">{{ item.msgLevel }}</a-tag>
                  <a-tag v-if="item.msgLevel === '普通'" color="orange">{{ item.msgLevel }}</a-tag>
                  <a-tag v-if="item.msgLevel === '紧急'" color="red">{{ item.msgLevel }}</a-tag>
                  <span class="font-semibold"> {{ item.msgTitle }}</span>
                </div>
                <div class="text-xs text-grey mt-2">
                  <span class="mr-6">{{ item.sendTime }}</span>
                  <span>{{ item.sendEmpName }}</span>
                </div>
              </template>
              <div v-html="item.msgContent"></div>
              <!-- <div v-if="!activeCollapse.includes(item.id)" class="text-xs text-grey mt-2">
                <span class="mr-6">{{ item.recTime }}</span>
                <span>{{ item.destEmpName }}</span>
              </div> -->
            </a-collapse-panel>
          </a-collapse>
          <div v-else class="text-center">
            <a-empty description="暂无数据" />
          </div>
        </div>
        <div class="my-4 text-center">
          <a-button class="w-48" type="primary" ghost @click="onOpenModal">发送私信</a-button>
        </div>
      </div>
    </template>
    <div class="w-full text-center" @click="openPopover = true">
      <a-badge :count="unReadCount" :style="{ minWidth: '16px', height: '16px', lineHeight: '16px' }" :offset="[4, -2]">
        <BellOutlined class="text-base text-white" />
      </a-badge>
    </div>
  </a-popover>
  <a-modal v-model:open="openModal" :width="680" centered title="发送私信" :ok-button-props="{ disabled: !isCompleted }" @ok="onOk" @cancel="onCancel">
    <a-form ref="formRef" class="form-style-flex" :model="formState" :label-col="{ style: { width: '80px' } }">
      <a-form-item label="标题" class="w-full" v-bind="validateInfos.msgTitle">
        <a-input v-model:value="formState.msgTitle" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="消息内容" class="w-full" v-bind="validateInfos.msgContent">
        <a-textarea v-model:value="formState.msgContent" :rows="6" placeholder="请输入" />
      </a-form-item>
      <a-form-item label="消息级别" class="w-2/3" v-bind="validateInfos.msgLevelId">
        <a-radio-group v-model:value="formState.msgLevelId">
          <a-radio v-for="item in msgLevelList" :key="item.id" :value="item.id">{{ item.msgLevel }}</a-radio>
        </a-radio-group>
      </a-form-item>
      <a-form-item label="语音播报" class="w-1/3">
        <a-switch v-model:checked="formState.isBroadcast" un-checked-value="0" checked-value="1" />
      </a-form-item>
      <a-form-item label="通知对象" class="w-2/3 pr-12" v-bind="validateInfos.destEmpNames">
        <SelectTable
          v-if="formState.range === 2"
          v-model:value="formState.destEmpNames"
          multiple
          :auto-mark="false"
          type="员工"
          placeholder="请选择"
          @select="onSelect"
        />
        <!-- 分组 -->
        <a-select
          v-else-if="formState.range === 1"
          v-model:value="formState.destGroupIds"
          mode="multiple"
          show-search
          max-tag-count="responsive"
          placeholder="请选择"
          :options="groupList"
        />
      </a-form-item>
      <a-form-item label="" class="w-1/3">
        <a-radio-group v-model:value="formState.range" @change="onChangeGroup">
          <a-radio :value="1">分组</a-radio>
          <a-radio :value="2">个人</a-radio>
        </a-radio-group>
      </a-form-item>
    </a-form>
  </a-modal>
  <contextHolder />
</template>
<script setup>
import { h, ref } from 'vue'
import { BellOutlined } from '@ant-design/icons-vue'
import { message, notification } from 'ant-design-vue'
import useUserStore from '@/store/user'

const userStore = useUserStore()
const [api, contextHolder] = notification.useNotification()
const formState = ref({ isBroadcast: '0', msgLevelId: null, range: 1 })
const openModal = ref(false)
const openPopover = ref(false)
const unReadCount = ref(0)
const activeTab = ref('0')
const dataSource = ref([])
const groupList = ref([])
const activeCollapse = ref([])
const rulesState = ref({
  msgTitle: [{ required: true, message: '请输入通知标题' }],
  msgContent: [{ required: true, message: '请输入通知内容' }],
  destEmpNames: [{ required: true, message: '请选择通知对象' }],
  msgLevelId: [{ required: true, message: '请输入消息级别' }]
})
const { isCompleted, resetFields, validate, validateInfos } = useForm(formState, rulesState)
const sendNotification = (msgData) => {
  api.info({
    message: h('div', { onClick: () => (openPopover.value = true) }, msgData.msgTitle),
    description: h('div', { onClick: () => (openPopover.value = true) }, [
      h('div', msgData.msgContent),
      h('div', { class: 'flex justify-between mt-2 -mb-2 pr-6 text-grey' }, [
        h('div', '通知人：' + (msgData.sendEmpName || '')),
        h('div', '通知时间：' + (msgData.sendTime || ''))
      ])
    ]),
    placement: 'bottomRight'
  })
}

// const refresh = () => {
//   this.getRoomInfo()
//   this.staticData.wsClosed && this.reconnectSocket()
// }
const msgLevelList = ref([])
const getMsgLevel = async () => {
  const { data, code, msg } = await post('/common/mqcommon/getMqDictMsglevelList')
  if (code !== 0) return message.error(msg)
  formState.value.msgLevelId = data[0].id
  msgLevelList.value = data
}
const wsUrl = ref('')
const getWsUrl = async () => {
  wsUrl.value = getSystemConfig('SYSTEM_MESSAGE_WEBSOCKET_URL')
}
const onPopoverChange = (val) => {
  openPopover.value = val
  activeTab.value = '0'
  val && getMsgList()
}
const pageNum = ref(1)
const pageTotal = ref(0)
const getMsgList = async (isLoadMore = false) => {
  const { data, code, msg, total } = await post('/common/mqcommon/getUserMessagesList', {
    empId: userStore.empId,
    pageNum: isLoadMore ? pageNum.value : 1,
    pageSize: 10,
    readIp: '',
    readStatus: activeTab.value //阅读状态;0:未读|1：已读|2：失效
  })
  if (code !== 0) return message.error(msg)
  if (activeTab.value === '0') {
    unReadCount.value = total
  }
  pageTotal.value = total
  if (isLoadMore) {
    dataSource.value = [...dataSource.value, ...data]
  } else {
    pageNum.value = 1
    dataSource.value = data
  }
}
const getGroupList = async () => {
  const { data, code, msg } = await post('/operation/opex/getEmpGroupEntityList', {})
  if (code !== 0) return message.error(msg)
  groupList.value = data.map((item) => {
    return {
      label: item.groupName,
      value: item.id
    }
  })
}
const initWS = () => {
  const synth = window.speechSynthesis
  const msg = new SpeechSynthesisUtterance()
  const websocket = new WebSocket(`ws://${wsUrl.value}/websocket/${userStore.empId}`)
  websocket.onopen = () => console.info('ws连接成功')
  websocket.onclose = () => ({})
  websocket.onmessage = function (res) {
    const msgData = JSON.parse(res.data || '')
    getMsgList()
    sendNotification(msgData)
    if (msgData.isBroadcast === '1') {
      msg.text = res.data
      msg.lang = 'zh-CN' // 使用的语言:中文
      msg.volume = 1 // 声音音量：1
      msg.rate = 1 // 语速：1
      msg.pitch = 1 // 音高：1
      synth.speak(msg) // 播放
    }
  }
  websocket.onerror = function () {
    console.error('ws连接失败')
  }
}
const onCancel = () => {
  openModal.value = false
  formState.value = { isBroadcast: '0', msgLevelId: null, range: 1 }
  resetFields()
}
const scrollRef = ref(null)
const onChangeTab = () => {
  dataSource.value = []
  getMsgList()
  scrollRef.value.scrollTo(0, 0)
}
const onOk = async () => {
  await validate()
  let destEmpIds = []
  if (formState.value.range === 2) {
    destEmpIds = formState.value.destEmpNames.split('，').map((item) => {
      return selectEmpMap.value[item].empId
    })
  }
  const params = {
    ...formState.value,
    destEmpIds,
    msgType: '1',
    sendEmpId: userStore.empId
  }
  const { code, msg } = await post('/common/mqcommon/doSaveMqRecordEntity', params)
  if (code !== 0) return message.error(msg)
  message.success('发送成功')
  getMsgList()
  openModal.value = false
}
const selectEmpMap = ref({})
const onChangeGroup = () => {
  formState.value.destEmpIds = null
  formState.value.destEmpNames = null
  formState.value.destGroupIds = undefined
  selectEmpMap.value = {}
}
const onSelect = (select) => {
  selectEmpMap.value[select.empName] = select
  // formState.value.destEmpId = formState.value.destEmpId ? formState.value.destEmpId + '，' + select.empId : select.empId
  formState.value.destEmpNames = formState.value.destEmpNames ? formState.value.destEmpNames + '，' + select.empName : select.empName
}
// const reconnectSocket = () => {
//   if (APP.global.roomShow && this.staticData.reconnectNum < 5) {
//     this.initWS()
//     this.staticData.reconnectNum++
//   } else {
//     this.staticData.ws.close()
//     this.staticData.ws = null
//   }
// }
const onChangeCollapse = async (item) => {
  item.isRead = true
  const { code, msg } = await post('/common/mqcommon/doSaveMqReadRecordEntity', {
    id: item.id,
    readStatus: 1
  })
  if (code !== 0) return message.error(msg)
}
const onReadAll = async () => {
  const { code, msg } = await post('/common/mqcommon/allRead', {
    empId: userStore.empId
  })
  if (code !== 0) return message.error(msg)
  message.success('全部已读成功')
  getMsgList()
}
const onScroll = (event) => {
  const { scrollTop, clientHeight, scrollHeight } = event.target
  if (scrollTop + clientHeight >= scrollHeight) {
    // 滚动条到达底部，触发懒加载
    loadMore()
  }
}
const loadMore = () => {
  if (pageNum.value * 10 >= pageTotal.value) return
  pageNum.value++
  getMsgList(true)
}
const onOpenModal = () => {
  getGroupList()
  openModal.value = true
  openPopover.value = false
  formState.value = { isBroadcast: '0', msgLevelId: null, range: 1 }
  getMsgLevel()
  resetFields()
}
onMounted(async () => {
  getMsgList()
  await getWsUrl()
  initWS()
  // sendNotification({ msgTitle: '新通知test', msgContent: '欢迎使用复软软件', sendEmpName: 'wz', sendTime: '10:22' })
})
</script>
<style lang="less" scoped>
:deep(.ant-collapse) {
  .ant-collapse-header {
    padding: 8px 12px !important;
  }
  .ant-collapse-item {
    position: relative;
    min-height: 60px;
    border-bottom: 1px solid #eeeeee;
  }
  .ant-collapse-item:last-child {
    border-bottom: 1px solid #eeeeee;
  }
}
</style>
